home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Info-Mac 4
/
Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso
/
Development
/
Source
/
POVSRC
/
SOURCE
/
NORMAL.C
< prev
next >
Wrap
Text File
|
1993-07-28
|
8KB
|
318 lines
/****************************************************************************
* normal.c
*
* This module implements solid texturing functions that perturb the surface
* normal to create a bumpy effect.
*
* from Persistence of Vision Raytracer
* Copyright 1993 Persistence of Vision Team
*---------------------------------------------------------------------------
* NOTICE: This source code file is provided so that users may experiment
* with enhancements to POV-Ray and to port the software to platforms other
* than those supported by the POV-Ray Team. There are strict rules under
* which you are permitted to use this file. The rules are in the file
* named POVLEGAL.DOC which should be distributed with this file. If
* POVLEGAL.DOC is not available or for more info please contact the POV-Ray
* Team Coordinator by leaving a message in CompuServe's Graphics Developer's
* Forum. The latest version of POV-Ray may be found there as well.
*
* This program is based on the popular DKB raytracer version 2.12.
* DKBTrace was originally written by David K. Buck.
* DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
*
*****************************************************************************/
/*
Some texture ideas garnered from SIGGRAPH '85 Volume 19 Number 3,
"An Image Synthesizer" By Ken Perlin.
Further Ideas Garnered from "The RenderMan Companion" (Addison Wesley)
*/
#include "frame.h"
#include "vector.h"
#include "povproto.h"
#include "texture.h"
extern unsigned short crctab[256];
void ripples (x, y, z, Tnormal, normal)
DBL x, y, z;
TNORMAL *Tnormal;
VECTOR *normal;
{
register int i;
VECTOR point;
register DBL length, scalar, index;
if (Options & DEBUGGING)
printf ("ripples %g %g %g", x, y, z);
for (i = 0 ; i < NUMBER_OF_WAVES ; i++)
{
point.x = x;
point.y = y;
point.z = z;
VSub (point, point, Wave_Sources[i]);
VDot (length, point, point);
if (length == 0.0)
length = 1.0;
length = sqrt(length);
index = length*Tnormal->Frequency
+ Tnormal -> Phase;
scalar = cycloidal (index) * Tnormal -> Amount;
if (Options & DEBUGGING)
printf (" index %g scalar %g length %g\n", index, scalar, length);
VScale (point, point, scalar/length/(DBL)NUMBER_OF_WAVES);
VAdd (*normal, *normal, point);
}
VNormalize (*normal, *normal);
}
void waves (x, y, z, Tnormal, normal)
DBL x, y, z;
TNORMAL *Tnormal;
VECTOR *normal;
{
register int i;
VECTOR point;
register DBL length, scalar, index, sinValue ;
if (Options & DEBUGGING)
printf ("waves %g %g %g\n", x, y, z);
for (i = 0 ; i < NUMBER_OF_WAVES ; i++)
{
point.x = x;
point.y = y;
point.z = z;
VSub (point, point, Wave_Sources[i]);
VDot (length, point, point);
if (length == 0.0)
length = 1.0;
length = sqrt(length);
index = (length * Tnormal -> Frequency * frequency[i])
+ Tnormal -> Phase;
sinValue = cycloidal (index);
scalar = sinValue * Tnormal -> Amount /
frequency[i];
VScale (point, point, scalar/length/(DBL)NUMBER_OF_WAVES);
VAdd (*normal, *normal, point);
}
VNormalize (*normal, *normal);
}
void bumps (x, y, z, Tnormal, normal)
DBL x, y, z;
TNORMAL *Tnormal;
VECTOR *normal;
{
VECTOR bump_turb;
if (Tnormal -> Amount == 0.0)
return; /* why are we here?? */
if (Options & DEBUGGING)
printf ("bumps %g %g %g\n", x, y, z);
DNoise (&bump_turb, x, y, z); /* Get Normal Displacement Val. */
VScale(bump_turb, bump_turb, Tnormal->Amount);
VAdd (*normal, *normal, bump_turb); /* displace "normal" */
VNormalize (*normal, *normal); /* normalize normal! */
return;
}
/*
dents is similar to bumps, but uses noise() to control the amount of
dnoise() perturbation of the object normal...
*/
void dents (x, y, z, Tnormal, normal)
DBL x, y, z;
TNORMAL *Tnormal;
VECTOR *normal;
{
VECTOR stucco_turb;
DBL noise;
if (Tnormal -> Amount == 0.0)
return; /* why are we here?? */
noise = Noise (x, y, z);
noise = noise * noise * noise * Tnormal->Amount;
if (Options & DEBUGGING)
printf ("dents %g %g %g noise %g\n", x, y, z, noise);
DNoise (&stucco_turb, x, y, z); /* Get Normal Displacement Val. */
VScale (stucco_turb, stucco_turb, noise);
VAdd (*normal, *normal, stucco_turb); /* displace "normal" */
VNormalize (*normal, *normal); /* normalize normal! */
return;
}
/*
Ideas garnered from the April 89 Byte Graphics Supplement on RenderMan,
refined from "The RenderMan Companion, by Steve Upstill of Pixar, (C) 1990
Addison-Wesley.
*/
/*
wrinkles - This is my implementation of the dented() routine, using
a surface iterative fractal derived from DTurbulence. This is a 3-D vers.
(thanks to DNoise()...) of the usual version using the singular Noise()...
Seems to look a lot like wrinkles, however... (hmmm)
*/
void wrinkles (x, y, z, Tnormal, normal)
DBL x, y, z;
TNORMAL *Tnormal;
VECTOR *normal;
{
register int i;
register DBL scale = 1.0;
VECTOR result, value;
if (Tnormal -> Amount == 0.0)
return; /* why are we here?? */
if (Options & DEBUGGING)
printf ("wrinkles %g %g %g\n", x, y, z);
result.x = 0.0;
result.y = 0.0;
result.z = 0.0;
for (i = 0; i < 10 ; scale *= 2.0, i++)
{
DNoise(&value, x * scale, y * scale, z * scale); /* * scale,*/
result.x += FABS (value.x / scale);
result.y += FABS (value.y / scale);
result.z += FABS (value.z / scale);
}
VScale(result, result, Tnormal->Amount);
VAdd (*normal, *normal, result); /* displace "normal" */
VNormalize (*normal, *normal); /* normalize normal! */
return;
}
TNORMAL *Create_Tnormal ()
{
TNORMAL *New;
if ((New = (TNORMAL *) malloc (sizeof (TNORMAL))) == NULL)
MAError ("normal");
INIT_TPATTERN_FIELDS(New,NO_NORMAL);
New->Amount = 0.0;
return (New);
}
TNORMAL *Copy_Tnormal (Old)
TNORMAL *Old;
{
TNORMAL *New;
if (Old != NULL)
{
New = Create_Tnormal ();
*New = *Old;
New->Image = Copy_Image (Old->Image);
New->Trans = Copy_Transform (Old->Trans);
}
else
New = NULL;
return (New);
}
void Translate_Tnormal(Tnormal,Vector)
TNORMAL *Tnormal;
VECTOR *Vector;
{
TRANSFORM Trans;
if (Tnormal == NULL)
return;
Compute_Translation_Transform (&Trans, Vector);
Transform_Tnormal (Tnormal, &Trans);
}
void Rotate_Tnormal(Tnormal,Vector)
TNORMAL *Tnormal;
VECTOR *Vector;
{
TRANSFORM Trans;
if (Tnormal == NULL)
return;
Compute_Rotation_Transform (&Trans, Vector);
Transform_Tnormal (Tnormal, &Trans);
}
void Scale_Tnormal(Tnormal,Vector)
TNORMAL *Tnormal;
VECTOR *Vector;
{
TRANSFORM Trans;
if (Tnormal == NULL)
return;
Compute_Scaling_Transform (&Trans, Vector);
Transform_Tnormal (Tnormal, &Trans);
}
void Transform_Tnormal(Tnormal,Trans)
TNORMAL *Tnormal;
TRANSFORM *Trans;
{
if (Tnormal == NULL)
return;
if (!Tnormal->Trans)
Tnormal->Trans = Create_Transform ();
Compose_Transforms (Tnormal->Trans, Trans);
}
void Destroy_Tnormal(Tnormal)
TNORMAL *Tnormal;
{
if (Tnormal == NULL)
return;
Destroy_Image (Tnormal->Image);
Destroy_Transform (Tnormal->Trans);
free (Tnormal);
}
void Post_Tnormal (Tnormal)
TNORMAL *Tnormal;
{
if (Tnormal == NULL)
return;
if (Tnormal->Type == NO_NORMAL)
Error("No normal type given");
Tnormal->Flags |= POST_DONE;
return;
}